package com.skyable.device.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.skyable.common.api.cloud.SaService;
import com.skyable.common.common.ServiceResult;
import com.skyable.common.constants.exception.DeviceExcpConstants;
import com.skyable.common.constants.param.CommonParams;
import com.skyable.device.entity.ProductInfo;
import com.skyable.device.mapper.ProductInfoMapper;
import com.skyable.device.service.IProductInfoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author GaoYuan
 * @date 2019/11/5 9:40
 * @desc
 */
@Slf4j
@Service
public class ProductInfoServiceImpl extends ServiceImpl<ProductInfoMapper,ProductInfo> implements IProductInfoService {

    @Autowired
    SaService saService;
    //@Value("${skyable.log.server.address}")
    String logServerAddr;

    @Override
    public ServiceResult<ProductInfo> getProductInfoById(String productInfoId) {
        ServiceResult<ProductInfo> serviceResult = new ServiceResult<>();
        ProductInfo productInfo = baseMapper.selectById(productInfoId);
        serviceResult.setResult(productInfo);
        return serviceResult;
    }

    @Override
    @Transactional
    public ServiceResult<ProductInfo> createProductInfo(ProductInfo productInfo) {
        //设置请求body参数
        Map<String, Object> bodyMap = new HashMap<>();
        bodyMap.put("subDomainName",productInfo.getSubDomainName());
        bodyMap.put("subDomainDesc",productInfo.getDescription());
        bodyMap.put("secType",productInfo.getSecType());
        log.info("request method createSubDomain params:" + JSONObject.toJSONString((bodyMap)));
        String result = saService.createSubDomain(productInfo.getDomainId(),bodyMap);
        log.info("request method createSubDomain response:" + result);
        //设置返回结果
        ServiceResult<ProductInfo> serviceResult = new ServiceResult<>();
        JSONObject resultObj = JSONObject.parseObject(result);
        if(resultObj.containsKey("errorCode") || !resultObj.containsKey("subDomainId")) {
            serviceResult.setError(resultObj.getInteger("errorCode"),resultObj.getString("error"));
            return serviceResult;
        }
        Long subDomainId = resultObj.getLong("subDomainId");

        productInfo.setSubDomainId(subDomainId);
        baseMapper.insert(productInfo);

        // TODO 是否需要设置产品转发地址
        // String[] addrs = {logServerAddr};
        //设置产品数据转发地址
        //setPlatformDataReportServer(productInfo.getDomainId(),productInfo.getSubDomainId());
        //设置产品状态转发地址
        //setPlatformStatusReportServer(productInfo.getDomainId(),productInfo.getSubDomainId());

        serviceResult.setResult(productInfo);
        return serviceResult;
    }

    @Override
    public ServiceResult<Integer> updateProductInfo(ProductInfo productInfo) {
        ServiceResult<Integer> serviceResult = new ServiceResult<>();
        int result = baseMapper.updateById(productInfo);
        serviceResult.setResult(result);
        return serviceResult;
    }

    @Override
    public ServiceResult<IPage<ProductInfo>> getProductList(ProductInfo productInfo, Integer page, Integer limit) {
        ServiceResult<IPage<ProductInfo>> serviceResult = new ServiceResult<>();
        Page<ProductInfo> productInfoPage = new Page<>(page, limit);

        QueryWrapper<ProductInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.setEntity(productInfo);

        IPage<ProductInfo> result = baseMapper.selectPage(productInfoPage, queryWrapper);
        serviceResult.setResult(result);
        return serviceResult;
    }

    @Override
    public ServiceResult<List<ProductInfo>> getProductList(ProductInfo productInfo) {
        ServiceResult<List<ProductInfo>> serviceResult = new ServiceResult<>();
        List<ProductInfo> productInfoList = lambdaQuery().setEntity(productInfo).list();
        serviceResult.setResult(productInfoList);
        return serviceResult;
    }

    @Override
    public ServiceResult<Integer> getDomainProductCount(Long domainId) {
        ServiceResult<Integer> serviceResult = new ServiceResult<>();
        Integer count = lambdaQuery().eq(ProductInfo::getDomainId, domainId).count();
        serviceResult.setResult(count);
        return serviceResult;
    }

    @Override
    public ServiceResult<Integer> updateProductInfoAndApi(ProductInfo productInfo, String serviceIp, Integer servicePort) {
        ServiceResult<Integer> serviceResult = new ServiceResult<>();
        /**
         * 设置设备数据转发地址（转发至UDS服务）
         */
        String setDataResult = setUdsDataReportServer(productInfo.getDomainId(), productInfo.getSubDomainId(), serviceIp, servicePort);
        JSONObject dataResultObj = JSONObject.parseObject(setDataResult);
        if(dataResultObj != null && dataResultObj.containsKey(CommonParams.ERROR_CODE)) {
            serviceResult.setError(dataResultObj.getInteger(CommonParams.ERROR_CODE),dataResultObj.getString(CommonParams.ERROR));
            return serviceResult;
        }
        /**
         * 设置设备状态转发地址（转发至UDS服务）
         */
        String setStatusResult = setUdsStatusReportServer(productInfo.getDomainId(), productInfo.getSubDomainId(), serviceIp, servicePort);
        JSONObject statusResultObj = JSONObject.parseObject(setStatusResult);
        if(statusResultObj != null && statusResultObj.containsKey(CommonParams.ERROR_CODE)) {
            serviceResult.setError(statusResultObj.getInteger(CommonParams.ERROR_CODE),statusResultObj.getString(CommonParams.ERROR));
            return serviceResult;
        }
        int result = baseMapper.updateById(productInfo);
        serviceResult.setResult(result);
        return serviceResult;
    }

    @Override
    public ServiceResult<Long> getRedirectInfo(Long subDomainId) {
        //设置返回结果
        ServiceResult<Long> serviceResult = new ServiceResult<>();
        ProductInfo productInfo = baseMapper.selectById(subDomainId);
        if(productInfo == null) {
            serviceResult.setError(DeviceExcpConstants.ERROR_CODE_QUERY_PRODUCT,DeviceExcpConstants.ERROR_MSG_QUERY_PRODUCT);
            return serviceResult;
        }
        serviceResult.setResult(productInfo.getServiceId());
        return serviceResult;
    }

    /**
     * 设置UDS数据转发地址（转发至平台）
     * @param domainId
     * @param subDomainId
     * @return
     */
    @Override
    public String setPlatformDataReportServer(Long domainId, Long subDomainId) {
        String[] addrs = {logServerAddr};
        //设置产品数据转发地址
        Map<String,Object> setDataReportMap = new HashMap<>();
        setDataReportMap.put("targetType","custom");
        setDataReportMap.put("addrs",addrs);
        setDataReportMap.put("uri","/public/report/deviceReport");
        setDataReportMap.put("timeout", 2000);
        setDataReportMap.put("retryCount", 2);
        log.info("interface setDataReportServer request params:" + JSONObject.toJSONString((setDataReportMap)));
        String setDataReportResult = saService.setDataReportServer(domainId,subDomainId,setDataReportMap);
        log.info("interface setDataReportServer response:" + setDataReportResult);
        return setDataReportResult;
    }

    /**
     * 设置UDS状态转发地址（转发至平台）
     * @param domainId
     * @param subDomainId
     * @return
     */
    @Override
    public String setPlatformStatusReportServer(Long domainId, Long subDomainId) {
        String[] addrs = {logServerAddr};
        //设置产品状态转发地址
        Map<String,Object> setStatusReportMap = new HashMap<>();
        setStatusReportMap.put("targetType","custom");
        setStatusReportMap.put("addrs",addrs);
        setStatusReportMap.put("uri","/public/report/statusReport");
        setStatusReportMap.put("timeout", 2000);
        setStatusReportMap.put("retryCount", 2);
        log.info("interface setStatusReportServer request params:" + JSONObject.toJSONString((setStatusReportMap)));
        String setStatusReportResult = saService.setStatusReportServer(domainId,subDomainId,setStatusReportMap);
        log.info("interface setStatusReportServer response:" + setStatusReportResult);
        return setStatusReportResult;
    }


    /**
     * 设置UDS数据转发地址（转发至UDS）
     * @param domainId
     * @param serviceIp
     * @param servicePort
     * @return
     */
    private String setUdsDataReportServer(Long domainId, Long subDomainId, String serviceIp, Integer servicePort) {
        String[] addrs = {serviceIp + ":" + servicePort};
        Map<String,Object> setDataMap = new HashMap<>();
        setDataMap.put("targetType", "custom");
        setDataMap.put("addrs", addrs);
        setDataMap.put("uri", "/deviceReport");
        setDataMap.put("timeout", 1000);
        setDataMap.put("retryCount", 2);
        log.info("interface setStatusReportServer request params:" + JSONObject.toJSONString((setDataMap)));
        String setDataResult = saService.setDataReportServer(domainId, subDomainId, setDataMap);
        log.info("interface setStatusReportServer response:" + setDataResult);
        return setDataResult;
    }

    /**
     * 设置UDS状态转发地址（转发至UDS）
     * @param domainId
     * @param subDomainId
     * @param serviceIp
     * @param servicePort
     * @return
     */
    private String setUdsStatusReportServer(Long domainId, Long subDomainId, String serviceIp, Integer servicePort) {
        String[] addrs = {serviceIp + ":" + servicePort};
        Map<String,Object> setDataMap = new HashMap<>();
        setDataMap.put("targetType", "custom");
        setDataMap.put("addrs", addrs);
        setDataMap.put("uri", "/statusReport");
        setDataMap.put("timeout", 1000);
        setDataMap.put("retryCount", 2);
        log.info("interface setStatusReportServer request params:" + JSONObject.toJSONString((setDataMap)));
        String setStatusResult = saService.setStatusReportServer(domainId, subDomainId, setDataMap);
        log.info("interface setStatusReportServer response:" + setStatusResult);
        return setStatusResult;
    }

    @Override
    public ServiceResult<List<ProductInfo>> getProductListByServiceId(Long serviceId) {
        ServiceResult<List<ProductInfo>> serviceResult = new ServiceResult<>();
        List<ProductInfo> productInfoList = lambdaQuery().eq(ProductInfo::getServiceId, serviceId).list();
        serviceResult.setResult(productInfoList);
        return serviceResult;
    }
}
